package ig.metrica;

import ejb.metrica.matriz.correlacion.MatrizCorrelacionSBBean;
import ig.finanzas.AccionPK;
import ig.finanzas.DefinidorCalculoCambioEsperado;
import ig.finanzas.EspeciePK;
import ig.finanzas.MonedaPK;
import ig.finanzas.ProductoPK;
import ig.finanzas.Tasa;
import ig.finanzas.TasaPK;
import ig.finanzas.riesgo.FactorRiesgoMatrizCorrelacion;
import ig.finanzas.riesgo.FactorRiesgoPersonal;
import ig.metrica.origenesdedatos.OrigenDeDatos;
import ig.metrica.origenesdedatos.OrigenDeDatosHome;
import ig.metrica.riesgo.FactorRiesgoPersonalMetrica;
import ig.util.excepciones.LogicaExcepcion;
import java.rmi.RemoteException;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Timestamp;
import java.sql.Types;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Enumeration;
import java.util.Hashtable;
import java.util.Iterator;
import javax.ejb.*;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import javax.sql.DataSource;

/**
 * This is the bean class for the ModeloSBean enterprise bean.
 * Created 25/04/2007 08:53:21 PM
 * @author jsanchez
 */
public class ModeloSBean implements SessionBean, ModeloSRemoteBusiness, ModeloSLocalBusiness {

    private SessionContext context;
    private static final String INITIAL_CONTEXT_FACTORY = "org.jnp.interfaces.NamingContextFactory";
    private static final String TIPO_PRODUCTO = "PRODUCTO";
    private static final String TIPO_ESPECIE = "ESPECIE";
    private static final String TIPO_MONEDA = "MONEDA";
    public static final int VALORACION_TIRCOMPRA = 0;
    public static final int VALORACION_REGISTRADA = 1;
    public static final int VALORACION_PRECIOMERCADO = 2;
    public static final int VALORACION_REGISTRADA_PYG = 3;
    private Connection conn = null;
//    private Connection conn1 = null;
    private PreparedStatement pstmt1 = null;
    private PreparedStatement pstmt2 = null;
    private PreparedStatement pstmt3 = null;
    private PreparedStatement pstmt4 = null;
    private PreparedStatement pstmt5 = null;

    // <editor-fold defaultstate="collapsed" desc="EJB infrastructure methods. Click the + sign on the left to edit the code.">
    // TODO Add code to acquire and use other enterprise resources (DataSource, JMS, enterprise bean, Web services)
    // TODO Add business methods or web service operations
    /**
     * @see javax.ejb.SessionBean#setSessionContext(javax.ejb.SessionContext)
     */
    public void setSessionContext(SessionContext aContext) {
        context = aContext;
    }

    /**
     * @see javax.ejb.SessionBean#ejbActivate()
     */
    public void ejbActivate() {

    }

    /**
     * @see javax.ejb.SessionBean#ejbPassivate()
     */
    public void ejbPassivate() {

    }

    /**
     * @see javax.ejb.SessionBean#ejbRemove()
     */
    public void ejbRemove() {

    }
    // </editor-fold>
    /**
     * See section 7.10.3 of the EJB 2.0 specification
     * See section 7.11.3 of the EJB 2.1 specification
     */
    public void ejbCreate() {
    // TODO implement ejbCreate if necessary, acquire resources
    // This method has access to the JNDI context so resource aquisition
    // spanning all methods can be performed here such as home interfaces
    // and data sources.
    }

    public Connection getConexion(String datasource) throws NamingException, SQLException {
        Context ctx = new InitialContext();
        DataSource ds = (DataSource) ctx.lookup("java:/" + datasource);
        Connection c = ds.getConnection();
        return c;

    }

    // Add business logic below. (Right-click in editor and choose
    // "EJB Methods > Add Business Method" or "Web Service > Add Operation")
    public Integer create(ig.metrica.ModelosDTO DTO) throws java.lang.Exception {
        try {
            //Se asignan los valores especificados a sus respectivos atributos.
            this.closeStatemente(pstmt1);
            this.closeStatemente(pstmt2);
            this.closeStatemente(pstmt3);
            this.closeStatemente(pstmt4);
            this.closeStatemente(pstmt5);

            //Se guardan las propiedades en la base de datos.

            conn = getConexion("METRICADW");
            ResultSet r;
            Iterator i;

            //Se obtiene el consecutivo del modelo
            pstmt1 = conn.prepareStatement("SELECT MAX(ID) AS MAXIMO FROM MODELOS");
            r = pstmt1.executeQuery();
            r.next();
            DTO.setId(r.getInt("MAXIMO") + 1);
            closeStatemente(pstmt1);
            //Se almacenan los datos basicos del modelo
            //ID, NOMBRE, BANDASR1RIESGO, BANDAS2RIESGO, BANDAS1LIQUIDEZ, FECHAINICIO, NUMDIAS, TIPOVALORACIONPUNTA

//            pstmt1 = connection .prepareStatement("INSERT INTO MODELOS VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)");
            pstmt1 = conn.prepareStatement("INSERT INTO MODELOS(ID,NOMBRE,BANDAS1RIESGO,BANDAS2RIESGO,BANDAS1LIQUIDEZ,FECHAINICIO,NUMDIAS,TIPOVALORACIONPUNTAS,IDMATRIZ,TIPO_RIESGO,TIPO_MODELO) VALUES (?,?,?,?,?,?,?,?,?,?,?)");

            pstmt1.setInt(1, DTO.getId());
            pstmt1.setString(2, DTO.getNombre());
            pstmt1.setString(3, DTO.getBandas1riesgo());
            pstmt1.setString(4, DTO.getBandas2riesgo());
            pstmt1.setString(5, DTO.getBandas1liquidez());
            if (DTO.getFechainicio() == null && DTO.getNumdias() == -1) {
                pstmt1.setNull(6, Types.NULL);
                pstmt1.setNull(7, Types.NULL);
            } else if (DTO.getFechainicio() != null) {
                pstmt1.setDate(6, new java.sql.Date(DTO.getFechainicio().getTime()));
                pstmt1.setNull(7, Types.NULL);
            } else {
                pstmt1.setNull(6, Types.NULL);
                pstmt1.setInt(7, DTO.getNumdias());
            }

            ///////////////
            if (DTO.getTipovaloracionpuntas() != -1) {
                pstmt1.setInt(8, DTO.getTipovaloracionpuntas());
            } else if (DTO.getTipovaloracionpuntas() == -1) {
                pstmt1.setNull(8, Types.NULL);
            }

            //////////////
            if (DTO.getIdmatriz() != -1) {
                pstmt1.setInt(9, DTO.getIdmatriz());
            } else if (DTO.getIdmatriz() == -1) {
                pstmt1.setInt(9, 1);
            }

            if (DTO.getTipoRiesgo() != -1) {
                pstmt1.setInt(10, DTO.getTipoRiesgo());
            } else if (DTO.getTipoRiesgo() == -1) {
                pstmt1.setInt(10, 1);
            }

            if (DTO.getTipoModelo() != -1) {
                pstmt1.setInt(11, DTO.getTipoModelo());
            } else if (DTO.getTipoModelo() == -1) {
                pstmt1.setInt(11, 1);
            }

            pstmt1.executeUpdate();
            closeStatemente(pstmt1);
            return DTO.getId();
        } catch (Exception e) {
            e.printStackTrace();
            throw new CreateException(e.toString());
        } finally {
            closeStatemente(pstmt1);
            closeStatemente(pstmt2);
            closeStatemente(pstmt3);
            closeStatemente(pstmt4);
            closeStatemente(pstmt5);
            closeStatemente(conn);
        }
    }

    public void actualizar(ig.metrica.ModelosDTO DTO) throws java.lang.Exception {
        //TODO implement actualizar
        int idInterna = DTO.getId();
        PreparedStatement p = null;
//        Connection connection =null;

        this.closeStatemente(pstmt1);
        this.closeStatemente(pstmt2);
        this.closeStatemente(pstmt3);
        this.closeStatemente(pstmt4);
        this.closeStatemente(pstmt5);
        this.closeStatemente(p);

        try {
//            if(this.validarDatos(DTO)){
            conn = getConexion("METRICADW");
            ResultSet r;
            Iterator i;
            //Se almacenan los datos basicos del modelo
            pstmt1 = conn.prepareStatement("Update Modelos Set NOMBRE=?,BANDAS1RIESGO=?,BANDAS2RIESGO=?,BANDAS1LIQUIDEZ=?,FECHAINICIO=?,NUMDIAS=?,TIPOVALORACIONPUNTAS=?,IDMATRIZ=?, TIPO_RIESGO=?, TIPO_MODELO=? Where ID=?");
            pstmt1.setString(1, DTO.getNombre());
            pstmt1.setString(2, DTO.getBandas1riesgo());
            pstmt1.setString(3, DTO.getBandas2riesgo());
            pstmt1.setString(4, DTO.getBandas1liquidez());
            if (DTO.getFechainicio() != null) {
                pstmt1.setDate(5, new java.sql.Date(DTO.getFechainicio().getTime()));
                pstmt1.setNull(6, Types.NULL);
            } else {
                pstmt1.setNull(5, Types.NULL);
                pstmt1.setInt(6, DTO.getNumdias());
            }

            pstmt1.setInt(7, DTO.getTipovaloracionpuntas());
            pstmt1.setInt(8, DTO.getIdmatriz());
            pstmt1.setInt(9, DTO.getTipoRiesgo());
            pstmt1.setInt(10, DTO.getTipoModelo());
            pstmt1.setInt(11, DTO.getId());
            pstmt1.executeUpdate();
            this.closeStatemente(pstmt1);
            //Se almacenan el comportamiento de liquidacion de las acciones
            //IDMODELO, ACCION, NUMDIAS
            i = DTO.getComportamientoAcciones().keySet().iterator();
            while (i.hasNext()) {
                AccionPK accionPK = (AccionPK) i.next();
                int numdiasAccion = ((Integer) DTO.getComportamientoAcciones().get(accionPK)).intValue();
                pstmt2 = conn.prepareStatement("Update Liquidacionacciones Set ACCION=?,NUMDIAS=? Where IDMODELO=?");
                pstmt2.setString(1, accionPK.getNombre());
                pstmt2.setInt(2, numdiasAccion);
                pstmt2.setInt(3, idInterna);
                pstmt2.executeUpdate();
                this.closeStatemente(pstmt2);
            }
            //Se almacenan en la base de datos la relacion entre la entidad y su factor de riesgo personal
//                pstmt3 = connection .prepareStatement("UPDATE ASOCIACIONFACTORES SET TIPOENTIDAD=?,ENTIDAD=?,IDFACTORRIESGOPERSONAL=? WHERE ID=? AND IDMODELO=?)");
            this.closeStatemente(pstmt4);
            pstmt4 = conn.prepareStatement("INSERT INTO FACTORESRIESGOPERSONALES VALUES (?, ?, ?, ?, ?, ?)");
//            INSERT INTO [dbo].[FACTORESRIESGOPERSONALES]([ID], [IDFACTORMATRIZ], [TIPO], [TASA], [TIPOCALCULOCAMBIOESPERADO], [IDCAMBIOESPERADO])

            this.limpiarTablas(idInterna);
            //Se obtiene el consecutivo a utilizar en la tabla de asociacion de factores

            p = conn.prepareStatement("SELECT MAX(ID) AS MAXIMO FROM ASOCIACIONFACTORES");
            r = p.executeQuery();
            r.next();
            int idasofac = r.getInt("MAXIMO");
            this.closeStatemente(p);
            //Obtengo el consecutivo a utilizar en la tabla de factores

            p = conn.prepareStatement("SELECT MAX(ID) AS MAXIMO FROM FACTORESRIESGOPERSONALES");
            r = p.executeQuery();
            r.next();
            int idfactper = r.getInt("MAXIMO");
            this.closeStatemente(p);

            //ID, FORMACALCULO, VALOR, NUMDIAS, NUMOBSERVACIONES, COEFICIENTECONFIANZA, LAMBDA, TIPODIFERENCIA, LONGPERIODO

            //Obtengo el consecutivo a utilizar en la tabla de cambio esperado

            p = conn.prepareStatement("SELECT MAX(ID) AS MAXIMO FROM CAMBIOSESPERADOS");
            r = p.executeQuery();
            r.next();
            int idcambio = r.getInt("MAXIMO");
            this.closeStatemente(p);

            ArrayList llaves = new ArrayList();
            llaves.addAll(DTO.getRelacionProductosFactores().keySet());
            llaves.addAll(DTO.getRelacionEspeciesFactores().keySet());
            llaves.addAll(DTO.getRelacionMonedasFactores().keySet());

//                System.out.println(DTO.getRelacionProductosFactores().size());
//                System.out.println(DTO.getRelacionMonedasFactores().size());
//                System.out.println(DTO.getRelacionEspeciesFactores().size());
//                printHT(DTO.getRelacionEspeciesFactores(),"relacionEspeciesFactores");

            Hashtable listaFactoresRegistrados = new Hashtable();
            Hashtable listaDefinidoresRegistrados = new Hashtable();
//                int contador=0;
            i = llaves.iterator();
            while (i.hasNext()) {
//                    contador++;
                Object llave = i.next();

                FactorRiesgoPersonal factor = null;
                String tipoEntidad = null;
                if (llave instanceof ProductoPK) {
                    tipoEntidad = TIPO_PRODUCTO;
                    factor = (FactorRiesgoPersonal) DTO.getRelacionProductosFactores().get(llave);
                } else if (llave instanceof EspeciePK) {
                    tipoEntidad = TIPO_ESPECIE;
                    factor = (FactorRiesgoPersonal) DTO.getRelacionEspeciesFactores().get(llave);
                } else if (llave instanceof MonedaPK) {
                    tipoEntidad = TIPO_MONEDA;
                    factor = (FactorRiesgoPersonal) DTO.getRelacionMonedasFactores().get(llave);
                }

//                    if (!listaFactoresRegistrados.containsKey(factor)){
                p = conn.prepareStatement("SELECT ID FROM FACTORESRIESGO WHERE IDMATRIZ=? AND NOMBRE=?");
                p.setInt(1, DTO.getIdmatriz());
                p.setString(2, factor.getFactorRiesgoMatrizCorrelacion().getNombre());
                r = p.executeQuery();
                if (r.next()) {
                    int idfactormatriz = r.getInt("ID");
                    this.closeStatemente(p);
                    int tipocalculo = factor.getTipoCalculoCambioEsperado();
                    TasaPK tasaPK = factor.getTasaPK();
                    if (!listaFactoresRegistrados.containsKey(factor)) {
                        idfactper++;
                        pstmt4 = conn.prepareStatement("INSERT INTO FACTORESRIESGOPERSONALES VALUES (?, ?, ?, ?, ?, ?)");
                        pstmt4.setInt(1, idfactper);
                        pstmt4.setInt(2, idfactormatriz);
                        pstmt4.setInt(3, factor.getTipo());
                        pstmt4.setInt(5, tipocalculo);
                        if (tasaPK == null) {
                            pstmt4.setString(4, null);
                        } else {
                            pstmt4.setString(4, tasaPK.getNombre());
                        }
                    }
                    if (factor.getTipoCalculoCambioEsperado() == FactorRiesgoPersonal.CAMBIOESPERADO_FACTORMATRIZ) {
                        try {
                            pstmt4.setNull(6, Types.NULL);
                        } catch (Exception e) {
                        }
                    } else {
                        if (!listaDefinidoresRegistrados.containsKey(factor.getDefinidorCalculoCambioEsperado())) {
                            DefinidorCalculoCambioEsperado def = factor.getDefinidorCalculoCambioEsperado();
                            byte forma = def.getFormaCalculoCambioEsperado();
                            pstmt5 = conn.prepareStatement("INSERT INTO CAMBIOSESPERADOS VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?)");
                            idcambio++;
                            pstmt5.setInt(1, idcambio);
                            pstmt5.setInt(2, forma);
                            pstmt5.setNull(3, Types.NULL);
                            pstmt5.setNull(4, Types.NULL);
                            pstmt5.setNull(5, Types.NULL);
                            pstmt5.setNull(6, Types.NULL);
                            pstmt5.setNull(7, Types.NULL);
                            pstmt5.setNull(8, Types.NULL);
                            pstmt5.setNull(9, Types.NULL);

                            if (forma == DefinidorCalculoCambioEsperado.FORMA_CALCULOCAMBIOESPERADO_VALORESPECIFICADO) {
                                pstmt5.setDouble(3, def.getValor());
                            } else if (forma == DefinidorCalculoCambioEsperado.FORMA_CALCULOCAMBIOESPERADO_NORMAL) {
                                pstmt5.setInt(5, def.getNumobservaciones());
                                pstmt5.setDouble(6, def.getCoeficienteconfianza());
                            } else if (forma == DefinidorCalculoCambioEsperado.FORMA_CALCULOCAMBIOESPERADO_EWMA) {
                                pstmt5.setInt(5, def.getNumobservaciones());
                                pstmt5.setDouble(6, def.getCoeficienteconfianza());
                                pstmt5.setDouble(7, def.getLambda());
                                pstmt5.setInt(8, def.getTipodiferencia());
                                pstmt5.setInt(9, def.getLongperiodo());

                            } else if (forma == DefinidorCalculoCambioEsperado.FORMA_CALCULOCAMBIOESPERADO_ELIECER ||
                                    forma == DefinidorCalculoCambioEsperado.FORMA_CALCULOCAMBIOESPERADO_ELIECER_NO_SUMAR_PROMEDIO ||
                                    forma == DefinidorCalculoCambioEsperado.FORMA_CALCULOCAMBIOESPERADO_ELIECER_NO_SUMAR_PROMEDIO_MAX_OBSERVACION ||
                                    /*
                                     * Modificado por Cristhiam Reina
                                     * 5 de agosto 2011
                                     * Nueva Condicion
                                     */
                                    forma == DefinidorCalculoCambioEsperado.FORMA_VALORACION_HISTORICA) {
                                pstmt5.setInt(5, def.getNumobservaciones());
                                pstmt5.setDouble(6, def.getCoeficienteconfianza());
                                pstmt5.setInt(8, def.getTipodiferencia());
                                pstmt5.setInt(9, def.getLongperiodo());
                            }
                            
                            /*
                             * Modificado por Cristhiam Reina
                             * 5 de agosto 2011
                             * Se agrego nuevo else if para FORMA_REGRESION_LINEAL
                            */
                            
                            else if (forma == DefinidorCalculoCambioEsperado.FORMA_REGRESION_LINIAL){
                                    
                                pstmt5.setInt(5, def.getNumobservaciones());
                                pstmt5.setInt(8, def.getTipodiferencia());
                                pstmt5.setInt(9, def.getLongperiodo());
                            }
                            if (tasaPK != null) {
                                if (getTipoTasa(tasaPK, DTO) != null) {
                                    if (getTipoTasa(tasaPK, DTO).equals(Tasa.TIPO_CURVA)) {
                                        pstmt5.setInt(4, def.getNumdias());
                                    }
                                } else {
                                    throw new LogicaExcepcion("No se encontro la tasa " + tasaPK);
                                }
                            }
                            pstmt5.executeUpdate();
                            this.closeStatemente(pstmt5);
                            listaDefinidoresRegistrados.put(def, new Integer(idcambio));

                        }
                        if (!listaFactoresRegistrados.containsKey(factor)) {
                            int idcambioesperado = ((Integer) listaDefinidoresRegistrados.get(factor.getDefinidorCalculoCambioEsperado())).intValue();
                            pstmt4.setInt(6, idcambioesperado);
                        }
                    }
                    if (!listaFactoresRegistrados.containsKey(factor)) {
                        listaFactoresRegistrados.put(factor, new Integer(idfactper));
                        pstmt4.executeUpdate();
                        this.closeStatemente(pstmt4);
                    }
                    int idfactorriesgo = ((Integer) listaFactoresRegistrados.get(factor)).intValue();
                    idasofac++;
                    pstmt3 = conn.prepareStatement("INSERT INTO ASOCIACIONFACTORES (ID, IDMODELO, TIPOENTIDAD, ENTIDAD, IDFACTORRIESGOPERSONAL)  VALUES(?,?,?,?,?)");
                    pstmt3.setInt(1, idasofac);
                    pstmt3.setInt(2, DTO.getId());
                    pstmt3.setString(3, tipoEntidad.trim());
                    pstmt3.setString(4, llave.toString().trim());
                    pstmt3.setInt(5, idfactorriesgo);
                    pstmt3.executeUpdate();
                    this.closeStatemente(pstmt3);
                }
//                    }else
//                         System.out.println("No almaceno cuando el contador es "+contador+" y la llave es :"+llave);
            }
//                System.out.println("contador:"+contador);
//            }
        } catch (Exception e) {
            e.printStackTrace();
            throw new CreateException(e.getMessage());
        } finally {
            this.closeStatemente(pstmt1);
            this.closeStatemente(pstmt2);
            this.closeStatemente(pstmt3);
            this.closeStatemente(pstmt4);
            this.closeStatemente(pstmt5);
            this.closeStatemente(p);
            this.closeStatemente(conn);
        }
    }

    public void delete(java.lang.Integer id) throws java.lang.Exception {
        //TODO implement delete
        Connection connection = null;
        try {
            connection = getConexion("METRICADW");
            ResultSet r, r2;
            closeStatemente(pstmt1);
            pstmt1 = connection.prepareStatement("DELETE FROM LIQUIDACIONACCIONES WHERE IDMODELO=? ");
            pstmt1.setInt(1, id);
            pstmt1.execute();
            this.closeStatemente(pstmt1);

            pstmt1 = connection.prepareStatement(
                    "SELECT TIPOENTIDAD, ENTIDAD, IDFACTORRIESGOPERSONAL " +
                    "FROM ASOCIACIONFACTORES " +
                    "WHERE IDMODELO=? ");
            pstmt1.setInt(1, id);
            r = pstmt1.executeQuery();
            Hashtable id_factorespersonales = new Hashtable();
            Hashtable id_cambioesperado = new Hashtable();
            while (r.next()) {
                int idfactorriesgopersonal = r.getInt("IDFACTORRIESGOPERSONAL");
                if (!id_factorespersonales.containsKey(new Integer(idfactorriesgopersonal))) {
                    closeStatemente(pstmt2);
                    pstmt2 = connection.prepareStatement(
                            "SELECT IDFACTORMATRIZ, TIPO, TASA, TIPOCALCULOCAMBIOESPERADO, IDCAMBIOESPERADO " +
                            "FROM FACTORESRIESGOPERSONALES " +
                            "WHERE ID=? ");
                    pstmt2.setInt(1, idfactorriesgopersonal);
                    r2 = pstmt2.executeQuery();
                    while (r2.next()) {
                        try {
                            Object temp = r2.getString("IDCAMBIOESPERADO");
                            if (temp != null) {
                                if (!id_cambioesperado.containsKey(Integer.parseInt(temp.toString()))) {
                                    closeStatemente(pstmt3);
                                    pstmt3 = connection.prepareStatement("DELETE FROM CAMBIOSESPERADOS WHERE ID=?");
                                    pstmt3.setInt(1, Integer.parseInt(temp.toString()));
                                    pstmt3.execute();
                                }
                            }
                        } catch (Exception e) {
                            e.printStackTrace();
                            throw e;
                        }
                    }
                    closeStatemente(pstmt2);
                    pstmt2 = connection.prepareStatement("DELETE FROM FACTORESRIESGOPERSONALES WHERE ID=? ");
                    pstmt2.setInt(1, idfactorriesgopersonal);
                    pstmt2.execute();
                }
            }
            closeStatemente(pstmt1);
            pstmt1 = connection.prepareStatement("DELETE FROM ASOCIACIONFACTORES WHERE IDMODELO=? ");
            pstmt1.setInt(1, id);
            pstmt1.execute();

            closeStatemente(pstmt1);
            pstmt1 = connection.prepareStatement("DELETE FROM MODELOS WHERE ID=? ");
            pstmt1.setInt(1, id);
            pstmt1.execute();

            closeStatemente(pstmt1);
            pstmt1 = connection.prepareStatement("DELETE FROM MODELOORIGENESDATOS  WHERE MODELO=?");
            pstmt1.setInt(1, id);
            pstmt1.execute();

            closeStatemente(pstmt1);
            pstmt1 = connection.prepareStatement("DELETE FROM CONFIGURACIONFLUJOS  WHERE IDMODELO=?");
            pstmt1.setInt(1, id);
            pstmt1.execute();

            closeStatemente(pstmt1);
            pstmt1 = connection.prepareStatement("DELETE FROM CONFIGURACIONBALANCES WHERE IDMODELO = ?");
            pstmt1.setInt(1, id);
            pstmt1.execute();

            closeStatemente(pstmt1);
            pstmt1 = connection.prepareStatement("DELETE FROM CONFIGURACIONFLUJOSFORMULADOS WHERE IDMODELO =?");
            pstmt1.setInt(1, id);
            pstmt1.execute();
        } catch (Exception e) {
            e.printStackTrace();
            throw e;
        } finally {
            closeStatemente(connection);
            closeStatemente(pstmt1);
            closeStatemente(pstmt2);
            closeStatemente(pstmt3);
        }
    }

    public Collection findAll() throws java.lang.Exception {
        Collection resultado = new ArrayList();
        Connection connection = null;
        ResultSet r = null;
        closeStatemente(pstmt1);
        try {
            connection = getConexion("METRICADW");
            pstmt1 = connection.prepareStatement("SELECT ID, NOMBRE, BANDAS1RIESGO, BANDAS2RIESGO, BANDAS1LIQUIDEZ, FECHAINICIO, NUMDIAS, TIPOVALORACIONPUNTAS, IDMATRIZ, TIPO_RIESGO,TIPO_MODELO FROM MODELOS");
            r = pstmt1.executeQuery();
            while (r.next()) {
                ModelosDTO DTO = new ModelosDTO();
                DTO.setNombre(r.getString("NOMBRE"));
                DTO.setId(r.getInt("ID"));
                DTO.setIdmatriz(r.getInt("IDMATRIZ"));
                DTO.setBandas1liquidez(r.getString("BANDAS1LIQUIDEZ"));
                DTO.setBandas1riesgo(r.getString("BANDAS1RIESGO"));
                DTO.setBandas2riesgo(r.getString("BANDAS2RIESGO"));
                DTO.setFechainicio(r.getTimestamp("FECHAINICIO"));
                DTO.setNumdias(r.getInt("NUMDIAS"));
                DTO.setTipovaloracionpuntas(r.getInt("TIPOVALORACIONPUNTAS"));
                DTO.setTipoRiesgo(r.getInt("TIPO_RIESGO"));
                DTO.setTipoModelo(r.getInt("TIPO_MODELO"));
                resultado.add(DTO);
            }
        } catch (Exception e) {
            e.printStackTrace();
            throw new FinderException(e.toString());
        } finally {
            this.closeStatemente(pstmt1);
            this.closeStatemente(pstmt2);
            this.closeStatemente(pstmt3);
            this.closeStatemente(pstmt4);
            this.closeStatemente(pstmt5);
            this.closeStatemente(connection);
        }
        return resultado;
    }

    public ModelosDTO findByNombre(java.lang.String nombre) throws java.lang.Exception {
        Connection connection = getConexion("METRICADW");
        ResultSet r = null;
        try {
            closeStatemente(pstmt1);
            pstmt1 = connection.prepareStatement(
                    "SELECT ID FROM MODELOS " +
                    "WHERE NOMBRE=? ");
            pstmt1.setString(1, nombre);
            r = pstmt1.executeQuery();
            if (r.next()) {
                Integer id = r.getInt("ID");
                closeStatemente(pstmt1);
                return this.findById(id);
            } else {
                return null;
            }
        } catch (Exception e) {
            e.printStackTrace();
            throw e;
        } finally {
            try {
                r.close();
            } catch (Exception exception) {
            }
            closeStatemente(pstmt1);
            closeStatemente(connection);
        }
    }

    public ModelosDTO findById(java.lang.Integer id) throws java.lang.Exception {
        //TODO implement findById
//        this.clenanPropiedades();
        ModelosDTO DTO = new ModelosDTO();
        conn = getConexion("METRICADW");
        ResultSet r, r2, r3;
        try {
            //ID, IDMODELO, TIPOENTIDAD, ENTIDAD, IDFACTORRIESGOPERSONAL
            closeStatemente(pstmt1);
            pstmt1 = conn.prepareStatement(
                    "SELECT NOMBRE, BANDAS1RIESGO, BANDAS2RIESGO, BANDAS1LIQUIDEZ, FECHAINICIO, NUMDIAS, TIPOVALORACIONPUNTAS, IDMATRIZ, TIPO_RIESGO, TIPO_MODELO " +
                    "FROM MODELOS " +
                    "WHERE ID=? ");
            pstmt1.setInt(1, id);
            r = pstmt1.executeQuery();
            Hashtable relacionProductosFactores = new Hashtable();
            Hashtable relacionEspeciesFactores = new Hashtable();
            Hashtable relacionMonedasFactores = new Hashtable();
            Hashtable id_factorespersonales = new Hashtable();
            Hashtable id_cambioesperado = new Hashtable();

            if (r.next()) {
                DTO.setId(id);
                DTO.setNombre(r.getString("NOMBRE"));
                DTO.setBandas1riesgo(r.getString("BANDAS1RIESGO"));
                DTO.setBandas2riesgo(r.getString("BANDAS2RIESGO"));
                DTO.setBandas1liquidez(r.getString("BANDAS1LIQUIDEZ"));
                DTO.setFechainicio(r.getDate("FECHAINICIO") != null ? new Timestamp(r.getDate("FECHAINICIO").getTime()) : null);
                
                DTO.setNumdias(r.getInt("NUMDIAS"));
                DTO.setTipovaloracionpuntas(r.getInt("TIPOVALORACIONPUNTAS"));
                DTO.setIdmatriz(r.getInt("IDMATRIZ"));
                DTO.setTipoRiesgo(r.getInt("TIPO_RIESGO"));
                DTO.setTipoModelo(r.getInt("TIPO_MODELO"));
                closeStatemente(pstmt1);
                pstmt1 = conn.prepareStatement("SELECT ACCION, NUMDIAS FROM LIQUIDACIONACCIONES WHERE IDMODELO=? ");
                pstmt1.setInt(1, id);
                r = pstmt1.executeQuery();
                Hashtable comportamientoAcciones = new Hashtable();
                while (r.next()) {
                    comportamientoAcciones.put(new AccionPK(r.getString("ACCION")), new Integer(r.getInt("NUMDIAS")));
                }
                DTO.setComportamientoAcciones(comportamientoAcciones);
                closeStatemente(pstmt1);
                pstmt1 = conn.prepareStatement("SELECT TIPOENTIDAD, ENTIDAD, IDFACTORRIESGOPERSONAL " +
                        "FROM ASOCIACIONFACTORES " +
                        "WHERE IDMODELO=? ");
                pstmt1.setInt(1, id);

                r = pstmt1.executeQuery();

                Collection FMatriz = (Collection) new MatrizCorrelacionSBBean().findById(DTO.getIdmatriz()).get("FACTORES");
                Collection FactoresMatriz = FMatriz != null ? FMatriz : new ArrayList();
                while (r.next()) {
                    String tipoEntidad = r.getString("TIPOENTIDAD");
                    String entidad = r.getString("ENTIDAD");
                    int idfactorriesgopersonal = r.getInt("IDFACTORRIESGOPERSONAL");
//                    System.out.println("entidad:"+entidad);
                    if (!id_factorespersonales.containsKey(new Integer(idfactorriesgopersonal))) {
                        closeStatemente(pstmt2);
//                        System.out.println("idfactorriesgopersonal  :"+idfactorriesgopersonal );
                        pstmt2 = conn.prepareStatement(
                                "SELECT IDFACTORMATRIZ, TIPO, TASA, TIPOCALCULOCAMBIOESPERADO, IDCAMBIOESPERADO " +
                                "FROM FACTORESRIESGOPERSONALES WHERE ID=? ");
                        pstmt2.setInt(1, idfactorriesgopersonal);
                        r2 = pstmt2.executeQuery();
                        Integer idfactormatrizcorrelacion = null;
                        Integer tipo = null;
                        TasaPK tasaPK = null;
                        String temp = null;
                        Integer idcambioesperado = null;
                        if (r2.next()) {
                            idfactormatrizcorrelacion = r2.getInt("IDFACTORMATRIZ");
                            tipo = r2.getInt("TIPO");
                            tasaPK = new TasaPK(r2.getString("TASA"));
                            temp = r2.getString("IDCAMBIOESPERADO");
//                    System.out.println("temp --->"+temp);
                            idcambioesperado = r2.getInt("IDCAMBIOESPERADO");
                        }
                        //System.out.println("temp:"+temp+"="+idcambioesperado );
                        if (temp != null) {
                            if (!id_cambioesperado.containsKey(new Integer(idcambioesperado))) {
                                closeStatemente(pstmt3);
                                pstmt3 = conn.prepareStatement(
                                        "SELECT FORMACALCULO, VALOR, NUMDIAS, NUMOBSERVACIONES, COEFICIENTECONFIANZA, LAMBDA, TIPODIFERENCIA, LONGPERIODO " +
                                        "FROM CAMBIOSESPERADOS " +
                                        "WHERE ID=?");
                                pstmt3.setInt(1, idcambioesperado);
                                r3 = pstmt3.executeQuery();
                                r3.next();
                                int formacalculo = r3.getInt("FORMACALCULO");
                                double valor = r3.getDouble("VALOR");
//                            System.out.println("valor--->"+valor);
                                String numdias = r3.getString("NUMDIAS");
                                int numobservaciones = r3.getInt("NUMOBSERVACIONES");
                                double coeficienteconfianza = r3.getDouble("COEFICIENTECONFIANZA");
                                double lambda = r3.getDouble("LAMBDA");
                                int tipodiferencia = r3.getInt("TIPODIFERENCIA");
                                int longperiodo = r3.getInt("LONGPERIODO");

                                DefinidorCalculoCambioEsperado definidor = null;
                                if (formacalculo == DefinidorCalculoCambioEsperado.FORMA_CALCULOCAMBIOESPERADO_VALORESPECIFICADO) {
                                    definidor = new DefinidorCalculoCambioEsperado(valor);
                                } else if (formacalculo == DefinidorCalculoCambioEsperado.FORMA_CALCULOCAMBIOESPERADO_EWMA) {
                                    definidor = new DefinidorCalculoCambioEsperado(lambda, numobservaciones, coeficienteconfianza, (byte) tipodiferencia, longperiodo);
                                } else if (formacalculo == DefinidorCalculoCambioEsperado.FORMA_CALCULOCAMBIOESPERADO_NORMAL) {
                                    definidor = new DefinidorCalculoCambioEsperado(numobservaciones, coeficienteconfianza);
                                } else if (formacalculo == DefinidorCalculoCambioEsperado.FORMA_CALCULOCAMBIOESPERADO_ELIECER) {
                                    definidor = new DefinidorCalculoCambioEsperado((byte) tipodiferencia, longperiodo, numobservaciones, coeficienteconfianza, true);
                                } else if (formacalculo == DefinidorCalculoCambioEsperado.FORMA_CALCULOCAMBIOESPERADO_ELIECER_NO_SUMAR_PROMEDIO) {
                                    definidor = new DefinidorCalculoCambioEsperado((byte) tipodiferencia, longperiodo, numobservaciones, coeficienteconfianza, false);
                                } else if (formacalculo == DefinidorCalculoCambioEsperado.FORMA_CALCULOCAMBIOESPERADO_ELIECER_NO_SUMAR_PROMEDIO_MAX_OBSERVACION) {
                                    definidor = new DefinidorCalculoCambioEsperado((byte) tipodiferencia, longperiodo, numobservaciones, coeficienteconfianza, null);
                                }

                                /*
                                 * Modificado por Cristhiam Reina
                                 * 5 de agosto 2011
                                 * Nueva Condicion
                                 */

                                else if (formacalculo == DefinidorCalculoCambioEsperado.FORMA_VALORACION_HISTORICA) {
                                    definidor = new DefinidorCalculoCambioEsperado(numobservaciones, coeficienteconfianza, (byte)tipodiferencia, longperiodo);
                                                                                    
                                } /*
                                 * Modificado por Cristhiam Reina
                                 * 7 De Febrero 2012
                                 * Nueva Condicion Para Regresion lineal
                                 */

                                else if (formacalculo == DefinidorCalculoCambioEsperado.FORMA_REGRESION_LINIAL) {
                                    definidor = new DefinidorCalculoCambioEsperado(numobservaciones, (byte)tipodiferencia, longperiodo);
                                                                                    
                                }



                                if (numdias != null) {
                                    definidor.setNumdias(new Integer(numdias).intValue());
                                }
                                id_cambioesperado.put(new Integer(idcambioesperado), definidor);

                            }
                        }
                        if (idcambioesperado != null) {
                            FactorRiesgoPersonal factor = null;
                            DefinidorCalculoCambioEsperado definidor = (DefinidorCalculoCambioEsperado) id_cambioesperado.get(idcambioesperado);

                            closeStatemente(pstmt3);
                            closeStatemente(pstmt4);
                            pstmt4 = conn.prepareStatement(
                                    "SELECT M.NOMBRE AS MATRIZ, FECHAPUBLICACION, F.NOMBRE AS FACTOR " +
                                    "FROM FACTORESRIESGO F, MATRICESCORRELACION M " +
                                    "WHERE M.ID=F.IDMATRIZ AND F.ID=? AND M.ID=? ");
                            pstmt4.setInt(1, idfactormatrizcorrelacion);
                            pstmt4.setInt(2, DTO.getIdmatriz());
                            ResultSet r4 = pstmt4.executeQuery();

                            if (r4.next()) {
                                FactorRiesgoMatrizCorrelacion frmc = null;
                                Iterator iterator = FactoresMatriz.iterator();
                                while (iterator.hasNext()) {//por ejemplo hay 7
                                    FactorRiesgoMatrizCorrelacion frmc1 = (FactorRiesgoMatrizCorrelacion) iterator.next();
                                    if (frmc1.getNombre().equals(r4.getString("FACTOR"))) {
                                        frmc = frmc1;
                                        break;
                                    }
                                }

                                byte TIPO_FACTORTASA_DESCUENTO = 2;
                                if (tipo == FactorRiesgoPersonal.TIPO_FACTORTASA) {
                                    factor = new FactorRiesgoPersonalMetrica(tasaPK, frmc, definidor);
                                } else if (tipo == FactorRiesgoPersonal.TIPO_FACTORTASA_DESCUENTO) {
                                    factor = new FactorRiesgoPersonalMetrica(tasaPK, frmc, definidor, TIPO_FACTORTASA_DESCUENTO);
                                } else {
                                    factor = new FactorRiesgoPersonalMetrica(frmc, definidor);
                                }
                                id_factorespersonales.put(new Integer(idfactorriesgopersonal), factor);
                            }
                        }
                    }
                    FactorRiesgoPersonal factor = (FactorRiesgoPersonal) id_factorespersonales.get(new Integer(idfactorriesgopersonal));
                    if (factor != null && tipoEntidad != null && tipoEntidad.equals(TIPO_PRODUCTO)) {
                        String[] tokens = entidad.split("-");
                        String libro = tokens[0];
                        String cuenta = tokens[1];
                        String producto = "";
                        for (int i = 2; i < tokens.length; i++) {
                            if (!producto.trim().equals("")) {
                                producto += "-";
                            }
                            producto += tokens[i];
                        }
                        relacionProductosFactores.put(new ProductoPK(libro, cuenta, producto), factor);
                    } else if (factor != null && tipoEntidad != null && tipoEntidad.equals(TIPO_ESPECIE)) {
                        relacionEspeciesFactores.put(new EspeciePK(entidad), factor);
                    } else if (factor != null && tipoEntidad != null && tipoEntidad.equals(TIPO_MONEDA)) {
                        relacionMonedasFactores.put(new MonedaPK(entidad), factor);
                    }
                }
            }
            DTO.setRelacionEspeciesFactores(relacionEspeciesFactores);
            DTO.setRelacionMonedasFactores(relacionMonedasFactores);
            DTO.setRelacionProductosFactores(relacionProductosFactores);
            return DTO;
        } catch (Exception e) {
            e.printStackTrace();
            throw e;
        } finally {
            closeStatemente(pstmt1);
            closeStatemente(pstmt2);
            closeStatemente(pstmt3);
            closeStatemente(pstmt4);
            closeStatemente(pstmt5);
            closeStatemente(conn);
        }
    }

    public String getTipoTasa(TasaPK tasaPK, ModelosDTO DTO) throws NamingException, FinderException, RemoteException, ClassNotFoundException, SQLException {
        InitialContext ctx = new InitialContext();
        OrigenDeDatosHome home = (OrigenDeDatosHome) ctx.lookup("ig.metrica.origenesdedatos.OrigenDeDatos");
        Collection CTasas = home.findByAll();
        Hashtable<String, String> ht = new Hashtable<String, String>();
        ht.put("IDMODELO", DTO.getId().toString());
        for (Object elem : CTasas) {
            if (((OrigenDeDatos) elem).getEntidad().trim().equals("TASAS")) {
                ArrayList datos = ((OrigenDeDatos) elem).obtenerDatos(ht);
                //ArrayList arregloCampos = ((OrigenDeDatos) elem).getArregloCampos();
                int mapeoNombreTasa = 0;//arregloCampos.indexOf("NOMBRE");
                int mapeoTipoTasa = 1;//arregloCampos.indexOf("TIPO");

                try {
                    ((OrigenDeDatos) elem).closePoolConnection();
                } catch (Exception e) {
                }

                Iterator i = datos.iterator();
                while (i.hasNext()) {
                    Object[] registro = (Object[]) i.next();
//                    System.out.println(tasaPK.getNombre());
                    if (((String) registro[mapeoNombreTasa]).trim().equals(tasaPK.getNombre())) {
                        return ((String) registro[mapeoTipoTasa]).trim();
                    }
                }
            }
        }
        return null;
    }

    private void limpiarTablas(Integer id) throws NamingException, SQLException {
        PreparedStatement pstmtSelect = null;
        PreparedStatement pstmtDELFRP = null;
        PreparedStatement pstmtDELCE = null;
        PreparedStatement pstmtDELAF = null;
        PreparedStatement pstmtSelectCE = null;
        Connection connection = getConexion("METRICADW");
        try {
            this.closeStatemente(pstmtSelectCE);
            this.closeStatemente(pstmtDELCE);
            pstmtSelectCE = connection.prepareStatement("SELECT CE.ID FROM MODELOS MO INNER JOIN ASOCIACIONFACTORES AF ON MO.ID= AF.IDMODELO INNER JOIN FACTORESRIESGOPERSONALES FRP ON AF.IDFACTORRIESGOPERSONAL =FRP.ID INNER JOIN CAMBIOSESPERADOS CE ON FRP.IDCAMBIOESPERADO = CE.ID WHERE MO.ID= ?");
            pstmtSelectCE.setInt(1, id);
            ResultSet _resultadoCE = pstmtSelectCE.executeQuery();
            while (_resultadoCE.next()) {
                //ELIMINA TODOS LOS CAMBIOS ESPERADOS RELACIONDOS CON LOS FACTORES QUE ESTAN RELACIONADO CON EL MODELO
                try {
                    if (_resultadoCE != null && _resultadoCE.getObject("ID") != null && !_resultadoCE.getObject("ID").toString().equals("")) {
                        pstmtDELCE = connection.prepareStatement("DELETE FROM CAMBIOSESPERADOS WHERE ID=?");
                        pstmtDELCE.setInt(1, _resultadoCE.getInt("ID"));
                        pstmtDELCE.executeUpdate();
                    }
                } catch (SQLException e) {
                    e.printStackTrace();
                    System.out.println("No se pudo ejecutar la consulta: DELETE FROM CAMBIOSESPERADOS WHERE ID=?");
                    throw e;
                } finally {
                    this.closeStatemente(pstmtDELCE);
                }
            }

            this.closeStatemente(pstmtSelectCE);
            this.closeStatemente(pstmtSelect);
            this.closeStatemente(pstmtDELFRP);
            pstmtSelect = connection.prepareStatement("SELECT ID,IDFACTORRIESGOPERSONAL FROM ASOCIACIONFACTORES WHERE IDMODELO=?");
            pstmtSelect.setInt(1, id);
            ResultSet _resultado = pstmtSelect.executeQuery();
            while (_resultado.next()) {
                //ELIMINA TODOS LOS FACTORESRIESGOSPERSONALES RELACIONDOS QUE ESTAN RELACIONADO CON EL MODELO
                try {
                    if (_resultado != null && _resultado.getObject("IDFACTORRIESGOPERSONAL") != null && !_resultado.getObject("IDFACTORRIESGOPERSONAL").toString().equals("")) {
                        pstmtDELFRP = connection.prepareStatement("DELETE FROM FACTORESRIESGOPERSONALES WHERE ID=?");
                        pstmtDELFRP.setInt(1, _resultado.getInt("IDFACTORRIESGOPERSONAL"));
                        pstmtDELFRP.executeUpdate();
                    }
                } catch (SQLException e) {
                    e.printStackTrace();
                    System.out.println("No se pudo ejecutar la consulta: DELETE FROM FACTORESRIESGOPERSONALES WHERE ID=?");
                    throw e;
                } finally {
                    this.closeStatemente(pstmtDELFRP);
                }
            }
            this.closeStatemente(pstmtDELAF);
            pstmtDELAF = connection.prepareStatement("DELETE FROM ASOCIACIONFACTORES WHERE IDMODELO=?");
            pstmtDELAF.setInt(1, id);
            pstmtDELAF.executeUpdate();
        } catch (SQLException e) {
            e.printStackTrace();
            System.out.println("No se pudo ejecutar la consulta: DELETE FROM ASOCIACIONFACTORES WHERE IDMODELO=?" + e.getMessage());
            throw e;
        } finally {
            this.closeStatemente(pstmtDELAF);
            this.closeStatemente(pstmtDELCE);
            this.closeStatemente(pstmtDELFRP);
            this.closeStatemente(pstmtSelect);
            this.closeStatemente(pstmtSelect);
            this.closeStatemente(connection);
        }
    }

    public void closeStatemente(PreparedStatement pst) {
        try {
            pst.close();
        } catch (Exception e) {
        }
    }

    public void closeStatemente(Connection conn) {
        try {
            conn.close();
        } catch (Exception e) {
        }
    }

    private void printHT(Hashtable ht, String name) {
        System.out.println("*******************");
        System.out.println("Name:" + name);
        Enumeration Key = ht.keys();
        while (Key.hasMoreElements()) {
            Object key = Key.nextElement();
            ig.metrica.riesgo.FactorRiesgoPersonalMetrica FACTOR = ((ig.metrica.riesgo.FactorRiesgoPersonalMetrica) ht.get(key));
            Byte TIPO = FACTOR.getTipo();
            String TASAPK = null;
            if (FACTOR.getTasaPK() != null) {
                TASAPK = FACTOR.getTasaPK().toString();
            }
            Byte TIPO_CAL_ESP = FACTOR.getTipoCalculoCambioEsperado();
            String FACTOR_MATRIZ = FACTOR.getFactorRiesgoMatrizCorrelacion().getNombre();

            System.out.println(key.toString().trim() + "=TIPO:" + TIPO + ",TASAPK:" + TASAPK + ",TIPO_CAL_ESP:" + TIPO_CAL_ESP + ",FACTOR_MATRIZ:" + FACTOR_MATRIZ);
        }
        System.out.println("*");
    }
    
    public static void main(String[] arg) {
        System.out.println(java.sql.Timestamp.valueOf("2008-01-01 00:00:00.0"));
    }
}
